home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / Sherlock 2.0 / DevLibSrc / Main_DevLib / LIBes.c < prev    next >
Text File  |  1996-04-07  |  8KB  |  528 lines

  1. /*
  2.     devlib: General stream-oriented standard error routines.
  3.     
  4.     All routines output various items to the "error stream."
  5.     The semantics of this stream are application-defined via
  6.     the routines es, ecnl, ecnls and ecblanks.
  7.  
  8.     source:  LIBes.c
  9.     started: November 4, 1993.
  10.     version:
  11.         March 14, 1996.
  12.             Use Microseconds() in ticks2msec for Symantec or Metrowerks compilers.
  13.         March 5, 1995.
  14.             Allowed sysbeep() call for Metrowerks compiler.
  15.         February 5, 1996.
  16.             Support for Microseconds() toolbox call.
  17.         November 30, 1995.
  18.             `es_assert_failed' and `es_internal_err' are now application-specific.
  19.         November 8, 1995.
  20.             Bug fix: epadhex does not truncate if the field is zero.
  21.             Call cvt routines instead of sprintf.
  22.             Made ejustify visible for use by LIBfloat.c.
  23.             Moved edouble and epaddouble to LIBfloat.c.
  24.         September 26, 1995
  25.             bug fix to etrunc.
  26. */
  27.  
  28. #include <LIBlib.h>
  29. #include <LIBcvt.h>        /* For when ES_USE_CVT is #defined. */
  30. #include <LIBes.h>
  31.  
  32.  
  33. #include <ctype.h>        /* For isprint */
  34. #include <string.h>        /* For strlen */
  35. #include <stdio.h>        /* For FILE */
  36.  
  37. /*
  38.     #define ES_USE_CVT to use routines in LIBcvt.c instead of sprintf.
  39.     This is a way of avoiding sprintf (and the floating point library).
  40.     
  41.     #undef ES_USE_CVT to avoid all calls to routines in LIBcvt.c.
  42. */
  43. #define ES_USE_CVT
  44.  
  45. /*
  46.     Size of the conversion buffers.
  47. */
  48. #define ES_BUF_SIZE 200
  49.  
  50. /*
  51.     Define global variables.
  52. */
  53. long io_line_count = 0;        /* Number of chars in current output line. */
  54. int es2os_flag = FALSE;        /* TRUE: all call to es stream go to os stream. */
  55.  
  56.  
  57.  
  58. void
  59. eangle(char * s)
  60. {
  61.     echar('<'); es(s); echar('>');
  62. }
  63.  
  64. void
  65. ebell(void)
  66. {
  67.     #if defined(THINK_C) || defined(SYMANTEC_C) || defined(__MWERKS__)
  68.         SysBeep(20);
  69.     #else
  70.         #if 0 /* We don't want to "print" this character. */
  71.             echar('\a');
  72.         #endif
  73.     #endif
  74. }
  75.  
  76. void
  77. eblank(void)
  78. {
  79.     echar(' ');
  80. }
  81.  
  82. void
  83. eblanks(register int n)
  84. {
  85.     int i;
  86.  
  87.     for(i = 0; i < n; i++) {
  88.         eblank();
  89.     }
  90. }
  91.  
  92. void
  93. ebool(bool b)
  94. {
  95.     epadbool(b, 0);
  96. }
  97.  
  98. void
  99. ebracket(char * s)
  100. {
  101.     echar('['); es(s); echar(']');
  102. }
  103.  
  104. void
  105. echar(int c)
  106. {
  107.     char buffer[2];
  108.  
  109.     buffer [0] = c;
  110.     buffer [1] = '\0';
  111.  
  112.     es(buffer);
  113. }
  114.  
  115. void
  116. ecs(void)
  117. {
  118.     es(", ");
  119. }
  120.  
  121. void
  122. ecurly(char * s)
  123. {
  124.     echar('{'); es(s); echar('}');
  125. }
  126.  
  127. void
  128. efrac(long a1, long a2)
  129. {
  130.     epadfrac(a1, a2, 0);
  131. }
  132.  
  133. void
  134. ehex(long hex)
  135. {
  136.     epadhex(hex, 0);
  137. }
  138.  
  139. void
  140. ehexchar(long hex)
  141. {
  142.     epadhex(hex & 0xff, 0);
  143. }
  144.  
  145.  
  146. void
  147. eint(int i)
  148. {
  149.     epadint(i, 0);
  150. }
  151.  
  152. void
  153. ejustify(char * buffer, int length, int field_length)
  154. {
  155.     if (field_length < 0) {
  156.  
  157.         /* Left justify */
  158.         es(buffer);
  159.         eblanks(-field_length - length);
  160.     }
  161.     else {
  162.  
  163.         /* Right justify */
  164.         eblanks(field_length - length);
  165.         es(buffer);
  166.     }
  167. }
  168.  
  169. void
  170. elong(long l)
  171. {
  172.     epadlong(l, 0);
  173. }
  174.  
  175. void
  176. elp(void)
  177. {
  178.     es("(");
  179. }
  180.  
  181. void
  182. emsec(long ticks)
  183. {
  184.     epadmsec(ticks,0);
  185. }
  186.  
  187. void
  188. enl(void)
  189. {
  190.     es("\n");
  191. }
  192.  
  193. void
  194. epadbool(bool b, int field)
  195. {
  196.     if (b) {
  197.         ejustify("TRUE", 4, field);
  198.     }
  199.     else {
  200.         ejustify("FALSE", 5, field);
  201.     }
  202. }
  203.  
  204. void
  205. epadchar(char c, int field)
  206. {
  207.     char buffer[2];
  208.  
  209.     buffer[0] = c;
  210.     buffer[1] = '\0';
  211.  
  212.     ejustify(buffer, 1, field);
  213. }
  214.  
  215. void
  216. epadfrac(long a1, long a2, int field)
  217. {
  218.     char buf [ES_BUF_SIZE];
  219.  
  220.     if (a2 == 0) {
  221.         es("0.0");
  222.         return;
  223.     }
  224.     
  225.     #ifdef ES_USE_CVT
  226.         cvt_frac(buf, ES_BUF_SIZE, a1, a2);
  227.         ejustify(buf, strlen(buf), field);
  228.     #else
  229.         ejustify(buf, sprintf(buf, "%ld.%ld", a1/a2, ((10 * a1)/a2) % 10), field);
  230.     #endif
  231. }
  232.  
  233. /*
  234.     Output a long in hex format, justified in a field of the given length.
  235. */
  236. #define abs(a) ((a < 0) ? -(a) : (a))
  237.  
  238. void
  239. epadhex(long hex, int field)
  240. {
  241.     char buf [ES_BUF_SIZE];
  242.     int n = 0;
  243.     int len = 0;
  244.  
  245.     #ifdef ES_USE_CVT
  246.         cvt_hex(buf, ES_BUF_SIZE, hex);
  247.     #else
  248.         sprintf(buf, "%lx", hex);
  249.     #endif
  250.  
  251.     len = strlen(buf);
  252.     if (len >= abs(field) && field != 0) {
  253.     
  254.         /* Truncate to the indicated number of digits. */
  255.         es(buf + len - abs(field));
  256.     }
  257.     else if (field > 0) {
  258.     
  259.         /* Zero pad on the left. */
  260.         n = field - len;
  261.         while (n-- > 0) {
  262.             echar('0');
  263.         }
  264.         es(buf);
  265.     }
  266.     else {
  267.         /* blank pad on the right. */
  268.         ejustify(buf, len, field);
  269.     }
  270. }
  271.  
  272. /*
  273.     Output an int, justified in a field of the given length.
  274. */
  275. void
  276. epadint(int i, int field)
  277. {
  278.     char buf [ES_BUF_SIZE];
  279.  
  280.     #ifdef ES_USE_CVT
  281.         cvt_int(buf, ES_BUF_SIZE, i);
  282.         ejustify(buf, strlen(buf), field);
  283.     #else
  284.         ejustify(buf, sprintf(buf, "%d", i), field);
  285.     #endif
  286. }
  287.  
  288. /*
  289.     Output blanks to pad an item of size length in a field of field_length.
  290. */
  291. void
  292. epadlen(int item_length, int field_length)
  293. {
  294.     eblanks(field_length - item_length);
  295. }
  296.  
  297. /*
  298.     Output a long, justified in a field of the given length.
  299. */
  300. void
  301. epadlong(long l, int field)
  302. {
  303.     char buf [ES_BUF_SIZE];
  304.  
  305.     #ifdef ES_USE_CVT
  306.         cvt_long(buf, ES_BUF_SIZE, l);
  307.         ejustify(buf, strlen(buf), field);
  308.     #else
  309.         ejustify(buf, sprintf(buf, "%ld", l), field);
  310.     #endif
  311. }
  312.  
  313. /*
  314.     Convert ticks to msec.
  315.     A tick is about 1.28 msec.
  316. */
  317. void
  318. epadmsec(long ticks, int field)
  319. {
  320.     epadlong(ticks2msec(ticks), field);
  321. }
  322.  
  323. /*
  324.     Output a parenthesized string, justified in a field of a given length.
  325. */
  326. void
  327. epadparen(char * s, int field)
  328. {
  329.     char buf [ES_BUF_SIZE];
  330.  
  331.     #ifdef ES_USE_CVT
  332.         cvt_paren(buf, ES_BUF_SIZE, s);
  333.         ejustify(buf, strlen(buf), field);
  334.     #else
  335.         ejustify(buf, sprintf(buf, "(%s)", s), field);
  336.     #endif
  337. }
  338.  
  339. /*
  340.     Output a parenthesized long, justified in a field of a given length.
  341. */
  342. void
  343. epadparenlong(long a, int field)
  344. {
  345.     char buf [ES_BUF_SIZE];
  346.  
  347.     #ifdef ES_USE_CVT
  348.         strcpy(buf, "(");
  349.         cvt_long(buf+1, ES_BUF_SIZE-2, a);
  350.         strcat(buf, ")");
  351.         ejustify(buf, strlen(buf), field);
  352.     #else
  353.         ejustify(buf, sprintf(buf, "(%ld)", a), field);
  354.     #endif
  355. }
  356.  
  357. /*
  358.     Output a pointer justified in a field of the given length.
  359. */
  360. void
  361. epadptr(void * p, int field)
  362. {
  363.     char buf [ES_BUF_SIZE];
  364.  
  365.     #ifdef ES_USE_CVT
  366.         cvt_ptr(buf, ES_BUF_SIZE, p);
  367.         ejustify(buf, strlen(buf), field);
  368.     #else
  369.         ejustify(buf, sprintf(buf, "%p", p), field);
  370.     #endif
  371. }
  372.  
  373. /*
  374.     Output a string justified in a field of the given length.
  375. */
  376. void
  377. epads(char * s, int field)
  378. {
  379.     if (s != NULL) {
  380.         ejustify(s, strlen(s), field);
  381.     }
  382.     else {
  383.         ejustify(" ", 1, field);
  384.     }
  385. }
  386.  
  387. /*
  388.     Output an unsigned int, justified in a field of the given length.
  389. */
  390. void
  391. epaduint(uint ui, int field)
  392. {
  393.     char buf [ES_BUF_SIZE];
  394.  
  395.     #ifdef ES_USE_CVT
  396.         cvt_uint(buf, ES_BUF_SIZE, ui);
  397.         ejustify(buf, strlen(buf), field);
  398.     #else
  399.         ejustify(buf, sprintf(buf, "%u", ui), field);
  400.     #endif
  401. }
  402.  
  403. /*
  404.     Output an unsigned long, justified in a field of the given length.
  405. */
  406. void
  407. epadulong(ulong ul, int field)
  408. {
  409.     char buf [ES_BUF_SIZE];
  410.  
  411.     #ifdef ES_USE_CVT
  412.         cvt_ulong(buf, ES_BUF_SIZE, ul);
  413.         ejustify(buf, strlen(buf), field);
  414.     #else
  415.         ejustify(buf, sprintf(buf, "%lu", ul), field);
  416.     #endif
  417. }
  418.  
  419. void
  420. eparen(char * s)
  421. {
  422.     echar('('); es(s); echar(')');
  423. }
  424.  
  425. void
  426. eplural(long n)
  427. {
  428.     if (n != 1) {
  429.         es("s");
  430.     }
  431. }
  432.  
  433. void
  434. epstring(char * p)
  435. {
  436.     int n = *p++;
  437.  
  438.     while(n--) {
  439.         echar(*p++);
  440.     }
  441. }
  442.  
  443. void
  444. eptr(void * p)
  445. {
  446.     epadptr(p, 0);
  447. }
  448.  
  449. void
  450. equote(char * s)
  451. {
  452.     echar('"'); es(s); echar('"');
  453. }
  454.  
  455. void
  456. eret(void)
  457. {
  458.     es("returns: ");
  459. }
  460.  
  461. void
  462. erpnl(void)
  463. {
  464.     es(")\n");
  465. }
  466.  
  467. void
  468. etab(void)
  469. {
  470.     es("\t");
  471. }
  472.  
  473. void
  474. etabs(register int tab_count)
  475. {
  476.     while (tab_count-- > 0) {
  477.         es("\t");
  478.     }
  479. }
  480.  
  481. void
  482. etrunc(char * s, int n)
  483. {
  484.     while (*s && n-- > 0) {
  485.         echar(*s++);    /* bug fix: 9/26/95: was *s */
  486.     }
  487. }
  488.  
  489. void
  490. euint(uint ui)
  491. {
  492.     epaduint(ui, 0);
  493. }
  494.  
  495. void
  496. eulong(ulong ul)
  497. {
  498.     epadulong(ul, 0);
  499. }
  500.  
  501. /*
  502.     Convert from ticks to msec.
  503. */
  504. long
  505. ticks2msec(long ticks)
  506. {
  507.     double dticks = ticks;
  508.  
  509.     #if defined(TUPLE_C)
  510.  
  511.         /*     A tick is about 1.28 msec. */
  512.         // return (long) ((dticks * 1.28) / 1000);
  513.         return (long) (dticks * 0.00128); // work around compiler bug
  514.         
  515.     #elif defined(THINK_C) || defined(SYMANTEC_C) || defined(__MWERKS__) || defined(applec)
  516.     
  517.         /* A tick is 1 microsec. */
  518.         return (long) (dticks/1000.0);
  519.  
  520.     #else
  521.  
  522.         /* A tick is 1/60 sec. */
  523.         // return (long) ((dticks * 1000) / 60);
  524.         return (long) (dticks * 16.6666666666); // work around compiler bug
  525.  
  526.     #endif
  527. }
  528.